//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2005
//
// Map view overlapped paths.
//

# include "StdAfx.h"
# include "Paths.h"
# include "Map.h"
# include "Position.h"
# include "fast_floor.h"
# include "Wrappers.h"
# include "Globals.h"

Paths_t g_Paths;

void DrawPaths (HDC _hDC, const rect_t & _rectVisible) {
	CCritSec::CLock lock (g_cs);

	if (g_Paths.empty ())
		return;

	// Get max points.
	size_t cMaxPoints = 0;
	Paths_t::const_iterator ip;
	for (ip = g_Paths.begin (); ip != g_Paths.end (); ++ ip) {
		const CPath_t & path = * ip;

		const size_t cPoints = path.points.size ();
		if (cMaxPoints < cPoints)
			cMaxPoints = cPoints;
	}

	if (cMaxPoints == 0)
		return;

	// Prepare points buffer.
	POINT * const pPoints = (POINT *) ::alloca (sizeof (POINT)*cMaxPoints);

	for (ip = g_Paths.begin (); ip != g_Paths.end (); ++ ip) {
		const CPath_t & path = * ip;
		if (path.bHidden)
			continue;

		const points_t & points = path.points;
		const size_t cPoints = points.size ();
		for (size_t c = 0; c < cPoints; ++ c) {
			const point_t & point = points [c];

			assert (c < cMaxPoints);
			pPoints [c].x = XToScreen (point.x);
			pPoints [c].y = YToScreen (point.y);
		}

		const size_t cHSTo   = path.cHSTo   < cPoints ? path.cHSTo   : cPoints;
		const size_t cHSFrom = path.cHSFrom < cHSTo   ? path.cHSFrom : cHSTo;

		// Draw polyline except the highlighted segment.
		{
			const HPEN hpen = ::CreatePen (PS_SOLID, path.cWidth, path.col);
			const HPEN hpenPrev = (HPEN) ::SelectObject (_hDC, hpen);

			if (cHSFrom > 0)
				::Polyline (_hDC, pPoints, cHSFrom + 1);
			if (cHSTo < cPoints - 1)
				::Polyline (_hDC, pPoints + cHSTo, cPoints - cHSTo);

			::SelectObject (_hDC, hpenPrev);
			::DeleteObject (hpen);
		}

		// Draw the highlighted segment.
		if (cHSFrom < cHSTo) {
			const HPEN hpen = ::CreatePen (PS_SOLID, path.cWidth, path.colHS);
			const HPEN hpenPrev = (HPEN) ::SelectObject (_hDC, hpen);

			::Polyline (_hDC, pPoints + cHSFrom, cHSTo - cHSFrom + 1);

			::SelectObject (_hDC, hpenPrev);
			::DeleteObject (hpen);
		}
	}
}

void DeletePath (CPath_t & _path) {
	CCritSec::CLock lock (g_cs);

	for (Paths_t::iterator ip = g_Paths.begin (); ip != g_Paths.end (); ++ ip) {
		CPath_t & path = * ip;
		if (& path == & _path) {
			g_Paths.erase (ip);
			return;
		}
	}
}

